package db

import (
	"errors"
	"hr/api/dto"

	"github.com/spf13/cast"
)

type UserInfo struct {
	User
	RoleName string `json:"role_name"`
	DeptName string `json:"dept_name"`
	PostName string `json:"post_name"`
}

type AttendanceManage struct {
	AppModel
	AttendanceID string `gorm:"size:64" json:"attendance_id"`
	Reason       string `json:"reason"`
	Latitude     string `gorm:"size:64" json:"latitude"`
	Longitude    string `gorm:"size:64" json:"longitude"`
	Address      string `gorm:"size:255" json:"address"`
	CreateBy     string `gorm:"size:128" json:"createBy"` // 创建人
	UpdateBy     string `gorm:"size:128" json:"updateBy"` // 更新人
	Remark       string `gorm:"size:255" json:"remark"`   //备注
	Status       string `gorm:"size:64;" json:"status"`
	UserId       string `gorm:"size:128;" json:"user_id"`
	UserInfo     `gorm:"-" json:"user"`
}

func (m *AttendanceManage) TableName() string {
	return "attendance_manage"
}

type AttendanceManageType struct {
	AttendanceManage
	AttendanceType string `json:"attendance_type"`
}

type AttendanceManagePageModel struct {
	Total    int64                  `json:"total"`
	Result   []AttendanceManageType `json:"result"`
	PageNo   int                    `json:"pageNo"`
	PageSize int                    `json:"pageSize"`
}

func ExportAttendance(no, dept, name, startDate, endDate string) ([]AttendanceManageType, error) {
	userList := make([]UserInfo, 0)
	userIds := make([]uint, 0)
	attendanceManageTypeList := make([]AttendanceManageType, 0)
	userDbs := GetInstance().Select("user.*, dept.name as dept_name").Joins("left join dept on dept.id = user.dept_id")
	if no == "" && dept == "" && name == "" && startDate == "" && endDate == "" {
		return nil, errors.New("请输入筛选条件")
	}

	if no != "" {
		userDbs.Where("no LIKE ?", "%"+no+"%")
	}
	if dept != "" {
		userDbs.Where("dept.name LIKE ?", "%"+dept+"%")
	}
	if name != "" {
		userDbs.Where("nick_name LIKE ?", "%"+name+"%")
	}
	if err := userDbs.Find(&userList).Error; err != nil {
		return nil, err
	}

	if len(userList) > 0 {
		for _, user := range userList {
			userIds = append(userIds, user.ID)
		}
	} else {
		return nil, errors.New("根据筛选条件没有找到任何记录")
	}

	dbs := GetInstance().Select("attendance_manage.*,dict_value.tag as attendance_type").
		Joins("left join dict_value on dict_value.name = attendance_manage.attendance_id").Where("dict_value.dict_id=23")

	if len(userIds) > 0 {
		dbs = dbs.Where("attendance_manage.user_id IN ?", userIds)
	}
	if startDate != "" {
		dbs = dbs.Where("attendance_manage.created_at > ?", startDate+" 00:00:00")
	}
	if endDate != "" {
		dbs = dbs.Where("attendance_manage.created_at < ?", endDate+" 23:59:59")
	}
	if err := dbs.Find(&attendanceManageTypeList).Error; err != nil {
		return nil, err
	}

	for i, manage := range attendanceManageTypeList {
		for _, user := range userList {
			if manage.UserId == cast.ToString(user.ID) {
				attendanceManageTypeList[i].UserInfo = user
			}
		}
	}
	return attendanceManageTypeList, nil
}

func GetAttendanceManagePaging(pagination dto.Pagination, no, dept, name, startDate, endDate string) (AttendanceManagePageModel, error) {
	result := AttendanceManagePageModel{
		Total:    0,
		Result:   make([]AttendanceManageType, 0),
		PageNo:   pagination.PageNo,
		PageSize: pagination.PageSize,
	}
	offset := (pagination.PageNo - 1) * pagination.PageSize

	userList := make([]UserInfo, 0)
	userIds := make([]uint, 0)
	userDbs := GetInstance().Select("user.*, dept.name as dept_name").Joins("left join dept on dept.id = user.dept_id")
	if no != "" {
		u := make([]UserInfo, 0)
		_ = userDbs.Where("no LIKE ?", "%"+no+"%").Find(&u).Error
		if len(u) > 0 {
			userList = append(userList, u...)
		} else {
			return result, nil
		}
	}

	if dept != "" {
		u := make([]UserInfo, 0)
		_ = userDbs.Where("dept.name LIKE ?", "%"+dept+"%").Find(&u).Error
		if len(u) > 0 {
			userList = append(userList, u...)
		} else {
			return result, nil
		}
	}

	if name != "" {
		u := make([]UserInfo, 0)
		_ = userDbs.Where("nick_name LIKE ?", "%"+name+"%").Find(&u).Error
		if len(u) > 0 {
			userList = append(userList, u...)
		} else {
			return result, nil
		}
	}

	if len(userList) > 0 {
		for _, user := range userList {
			userIds = append(userIds, user.ID)
		}
	}

	dbs := GetInstance().Select("attendance_manage.*,dict_value.tag as attendance_type").
		Joins("left join dict_value on dict_value.name = attendance_manage.attendance_id").Where("dict_value.dict_id=23")

	if len(userIds) > 0 {
		dbs = dbs.Where("attendance_manage.user_id IN ?", userIds)
	}
	if startDate != "" {
		dbs = dbs.Where("attendance_manage.created_at > ?", startDate+" 00:00:00")
	}
	if endDate != "" {
		dbs = dbs.Where("attendance_manage.created_at < ?", endDate+" 23:59:59")
	}
	dbs = dbs.Order("id desc")

	if err := dbs.Offset(offset).Limit(pagination.PageSize).Find(&result.Result).Error; err != nil {
		return result, err
	}
	if err := dbs.Offset(-1).Limit(-1).Count(&result.Total).Error; err != nil {
		return result, err
	}

	for i, manage := range result.Result {
		if len(userIds) > 0 {
			for _, user := range userList {
				if manage.UserId == cast.ToString(user.ID) {
					result.Result[i].UserInfo = user
				}
			}
		} else {
			u := &UserInfo{}
			_ = GetInstance().Select("user.*, dept.name as dept_name").Joins("left join dept on dept.id = user.dept_id").Where("user.id = ?", manage.UserId).First(&u)
			result.Result[i].UserInfo = *u
		}
	}
	return result, nil
}

func GetAttendanceManageByUserPaging(pagination dto.Pagination, userId string) (AttendanceManagePageModel, error) {
	result := AttendanceManagePageModel{
		Total:    0,
		Result:   make([]AttendanceManageType, 0),
		PageNo:   pagination.PageNo,
		PageSize: pagination.PageSize,
	}

	user := User{}
	GetInstance().Where("id=?", userId).First(&user)
	role := Role{}
	GetInstance().Where("id=?", user.RoleID).First(&role)

	offset := (pagination.PageNo - 1) * pagination.PageSize
	dbs := GetInstance().Select("attendance_manage.*,dict_value.tag as attendance_type").Joins("left join dict_value on attendance_manage.attendance_id = dict_value.id")

	if role.Code == "small_captain" {
		dbs = dbs.Where("attendance_manage.create_by = ?", userId)
	} else {
		dbs = dbs.Where("attendance_manage.user_id = ?", userId)
	}

	if err := dbs.Offset(offset).Limit(pagination.PageSize).Find(&result.Result).Error; err != nil {
		return result, err
	}
	if err := dbs.Offset(-1).Limit(-1).Count(&result.Total).Error; err != nil {
		return result, err
	}

	if len(result.Result) > 0 {
		for i, c := range result.Result {
			u := &UserInfo{}
			err := GetInstance().Select("user.*, dept.name as dept_name").Joins("left join dept on dept.id = user.dept_id").Where("user.id = ?", c.UserId).First(&u).Error
			if err == nil {
				result.Result[i].UserInfo = *u
			}
		}
	}
	return result, nil
}

func AttendanceSubmit(a dto.AttendanceRequest, id uint) (AttendanceManage, error) {
	d := AttendanceManage{
		AttendanceID: a.AttendanceID,
		Reason:       a.Reason,
		Latitude:     a.Latitude,
		Longitude:    a.Longitude,
		Address:      a.Address,
		CreateBy:     cast.ToString(id),
		UserId:       a.UserId,
		Remark:       a.Desc,
	}
	if err := GetInstance().Create(&d).Error; err != nil {
		return d, errors.New("创建失败")
	}
	if d.ID > 0 {
		u, _, tag := GetUsers(map[string]interface{}{
			"id": a.UserId,
		})
		if tag == "2" {
			d.User = u
		}
		return d, nil
	} else {
		return d, errors.New("创建失败")
	}
}
